package com.atguigu.spzx.order.service.impl;

import com.atguigu.spzx.cart.dto.CartItemRedisQueryRespDto;
import com.atguigu.spzx.cart.feign.CartFeignClient;
import com.atguigu.spzx.common.constant.OrderProcessEnum;
import com.atguigu.spzx.common.constant.OrderStatusEnum;
import com.atguigu.spzx.common.constant.PayTypeEnum;
import com.atguigu.spzx.common.entity.UserInfo;
import com.atguigu.spzx.common.exception.GuiguException;
import com.atguigu.spzx.common.result.ResultCodeEnum;
import com.atguigu.spzx.common.utils.AuthContextUtil;
import com.atguigu.spzx.common.utils.BeanUtils;
import com.atguigu.spzx.common.utils.CollectionUtils;
import com.atguigu.spzx.common.utils.PageUtils;
import com.atguigu.spzx.order.dto.OrderInfoDetailRespDto;
import com.atguigu.spzx.order.entity.OrderInfo;
import com.atguigu.spzx.order.entity.OrderItem;
import com.atguigu.spzx.order.entity.OrderLog;
import com.atguigu.spzx.order.mapper.OrderInfoMapper;
import com.atguigu.spzx.order.mapper.OrderItemMapper;
import com.atguigu.spzx.order.mapper.OrderLogMapper;
import com.atguigu.spzx.order.service.OrderInfoService;
import com.atguigu.spzx.order.vo.OrderInfoDetailRespVo;
import com.atguigu.spzx.order.vo.OrderInfoQueryRespVo;
import com.atguigu.spzx.order.vo.OrderInfoSaveReqVo;
import com.atguigu.spzx.order.vo.TradeRespVo;
import com.atguigu.spzx.product.dto.ProductSkuDetailRespDto;
import com.atguigu.spzx.product.feign.ProductFeignClient;
import com.atguigu.spzx.user.dto.UserAddressDetailsRespDto;
import com.atguigu.spzx.user.entity.UserAddress;
import com.atguigu.spzx.user.feign.UserFeignClient;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * OrderInfoServiceImpl
 * </p>
 *
 * @author flyduck
 * @since 2023/11/6
 */
@Service
public class OrderInfoServiceImpl implements OrderInfoService {

    @Autowired
    private CartFeignClient cartFeignClient;
    @Autowired
    private ProductFeignClient productFeignClient;
    @Autowired
    private OrderInfoMapper orderInfoMapper;
    @Autowired
    private OrderItemMapper orderItemMapper;
    @Autowired
    private OrderLogMapper orderLogMapper;
    @Autowired
    private UserFeignClient userFeignClient;

    /**
     * 确认下单
     * @return
     */
    @Override
    public TradeRespVo getTrade() {
        TradeRespVo tradeRespVo = new TradeRespVo();
        //获取购物车选中的商品
        List<TradeRespVo.TradeInnerOrderItem> orderItemList = new ArrayList<>();
        List<CartItemRedisQueryRespDto> allCheckedCartItem = cartFeignClient.getAllChecked();
        for (CartItemRedisQueryRespDto cartItemRedisQueryRespDto : allCheckedCartItem) {
            TradeRespVo.TradeInnerOrderItem orderItem = new TradeRespVo.TradeInnerOrderItem();
            orderItem.setSkuId(cartItemRedisQueryRespDto.getSkuId());
            orderItem.setSkuName(cartItemRedisQueryRespDto.getSkuName());
            orderItem.setSkuNum(cartItemRedisQueryRespDto.getSkuNum());
            orderItem.setSkuPrice(cartItemRedisQueryRespDto.getCartPrice());
            orderItem.setThumbImg(cartItemRedisQueryRespDto.getImgUrl());
            orderItemList.add(orderItem);
        }
        tradeRespVo.setOrderItemList(orderItemList);
        //获取支付总金额
        BigDecimal totalAmount = new BigDecimal(0);
        for (TradeRespVo.TradeInnerOrderItem orderItem : orderItemList) {
            totalAmount = totalAmount.add(orderItem.getSkuPrice().multiply(new BigDecimal(orderItem.getSkuNum())));
        }
        tradeRespVo.setTotalAmount(totalAmount);
        return tradeRespVo;
    }

    /**
     * 提交订单
     * @param vo
     * @return
     */
    @Override
    public Long submitOrder(OrderInfoSaveReqVo vo) {
        UserInfo userInfo = AuthContextUtil.getUserInfo();

        //订单项如果为空，抛出异常
        List<OrderInfoSaveReqVo.OrderInfoSaveInnerOrderItem> orderItemList = vo.getOrderItemList();
        if (CollectionUtils.isEmpty(orderItemList)) {
            throw new GuiguException(ResultCodeEnum.DATA_ERROR);
        }

        //校验商品库存是否充足：远程调用获取商品信息
        for (OrderInfoSaveReqVo.OrderInfoSaveInnerOrderItem orderItem : orderItemList) {
            ProductSkuDetailRespDto productSkuDetailRespDto = productFeignClient.getProductSkuBySkuId(orderItem.getSkuId());
            if (productSkuDetailRespDto == null) {
                throw new GuiguException(ResultCodeEnum.DATA_ERROR);
            }
            if (orderItem.getSkuNum() > productSkuDetailRespDto.getStockNum()) {
                throw new GuiguException(ResultCodeEnum.STOCK_LESS);
            }
        }

        //保存order_info信息：获取用户地址信息
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setOrderNo(String.valueOf(System.currentTimeMillis()));//订单编号
        orderInfo.setUserId(userInfo.getId());//用户id
        orderInfo.setNickName(userInfo.getNickName());//用户昵称

        //用户收货地址信息
        UserAddressDetailsRespDto userAddress = userFeignClient.getUserAddressById(vo.getUserAddressId());
        orderInfo.setReceiverName(userAddress.getName());
        orderInfo.setReceiverPhone(userAddress.getPhone());
        orderInfo.setReceiverTagName(userAddress.getTagName());
        orderInfo.setReceiverProvince(userAddress.getProvinceCode());
        orderInfo.setReceiverCity(userAddress.getCityCode());
        orderInfo.setReceiverDistrict(userAddress.getDistrictCode());
        orderInfo.setReceiverAddress(userAddress.getFullAddress());
        //订单金额
        BigDecimal totalAmount = new BigDecimal(0);
        for (OrderInfoSaveReqVo.OrderInfoSaveInnerOrderItem orderItem : orderItemList) {
            totalAmount = totalAmount.add(orderItem.getSkuPrice().multiply(new BigDecimal(orderItem.getSkuNum())));
        }
        orderInfo.setTotalAmount(totalAmount);
        orderInfo.setCouponAmount(new BigDecimal(0));
        orderInfo.setOriginalTotalAmount(totalAmount);
        orderInfo.setFeightFee(vo.getFeightFee());
        orderInfo.setPayType(PayTypeEnum.ALIPAY.getCode());
        orderInfo.setOrderStatus(OrderStatusEnum.PENDING_PAYMENT.getCode());
        orderInfoMapper.insert(orderInfo);

        //保存order_item信息
        for (OrderInfoSaveReqVo.OrderInfoSaveInnerOrderItem orderInfoSaveInnerOrderItem : orderItemList) {
            orderInfoSaveInnerOrderItem.setOrderId(orderInfo.getId());
            OrderItem orderItem = BeanUtils.toBean(orderInfoSaveInnerOrderItem, OrderItem.class);
            orderItemMapper.insert(orderItem);
        }

        //保存到order_log信息
        OrderLog orderLog = new OrderLog();
        orderLog.setOrderId(orderInfo.getId());
        orderLog.setProcessStatus(OrderProcessEnum.PENDING_PAYMENT.getCode());
        orderLog.setNote("提交订单");
        orderLogMapper.insert(orderLog);

        //把生成订单的商品从购物车中删除
        cartFeignClient.deleteChecked();

        return orderInfo.getId();
    }

    /**
     * 获取订单详情
     * @param orderId
     * @return
     */
    @Override
    public OrderInfoDetailRespVo getOrderInfoById(Long orderId) {
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        return BeanUtils.toBean(orderInfo, OrderInfoDetailRespVo.class);
    }

    /**
     * 立即购买
     * @param skuId
     * @return
     */
    @Override
    public TradeRespVo buy(Long skuId) {
        TradeRespVo tradeRespVo = new TradeRespVo();

        List<TradeRespVo.TradeInnerOrderItem> orderItemList = new ArrayList<>();
        ProductSkuDetailRespDto productSku = productFeignClient.getProductSkuBySkuId(skuId);
        TradeRespVo.TradeInnerOrderItem orderItem = new TradeRespVo.TradeInnerOrderItem();
        orderItem.setSkuId(skuId);
        orderItem.setSkuName(productSku.getSkuName());
        orderItem.setSkuNum(1);
        orderItem.setSkuPrice(productSku.getSalePrice());
        orderItem.setThumbImg(productSku.getThumbImg());
        orderItemList.add(orderItem);
        tradeRespVo.setOrderItemList(orderItemList);

        tradeRespVo.setTotalAmount(productSku.getSalePrice());

        return tradeRespVo;
    }

    /**
     * 获取订单分页列表
     * @param pageParam
     * @param orderStatus
     * @return
     */
    @Override
    public Page<OrderInfoQueryRespVo> getOrderInfoPageByOrderStatus(Page<OrderInfo> pageParam, Integer orderStatus) {
        Long userId = AuthContextUtil.getUserInfo().getId();
        //查询订单信息
        Page<OrderInfo> orderInfoPageList = orderInfoMapper.getOrderInfoPageByUserIdAndOrderStatus(pageParam,userId,orderStatus);
        Page<OrderInfoQueryRespVo> respVoPageList = PageUtils.convertTo(orderInfoPageList, OrderInfoQueryRespVo.class);
        //查询订单项
        respVoPageList.getRecords().forEach(respVoPage -> {
            List<OrderItem> orderItemList = orderItemMapper.getOrderItemListByOrderId(respVoPage.getId());
            List<OrderInfoQueryRespVo.OrderInfoInnerOrderItem> orderInfoInnerOrderItemList = BeanUtils.toBeanList(orderItemList, OrderInfoQueryRespVo.OrderInfoInnerOrderItem.class);
            respVoPage.setOrderItemList(orderInfoInnerOrderItemList);
        });
        return respVoPageList;
    }

    /**
     * 获取订单信息
     * @param orderNo
     * @return
     */
    @Override
    public OrderInfoDetailRespDto getOrderInfoByOrderNo(String orderNo) {
        OrderInfo orderInfo = orderInfoMapper.getOrderInfoByOrderNo(orderNo);
        OrderInfoDetailRespDto respDto = BeanUtils.toBean(orderInfo, OrderInfoDetailRespDto.class);

        List<OrderItem> orderItemList = orderItemMapper.getOrderItemListByOrderId(orderInfo.getId());
        List<OrderInfoDetailRespDto.OrderInfoDetailInnerOrderItem> orderInfoDetailInnerOrderItems = BeanUtils.toBeanList(orderItemList, OrderInfoDetailRespDto.OrderInfoDetailInnerOrderItem.class);
        respDto.setOrderItemList(orderInfoDetailInnerOrderItems);
        return respDto;
    }

    /**
     * 更新订单状态
     * @param orderNo
     * @param orderStatus
     */
    @Override
    public void updateOrderStatusByOrderNo(String orderNo, Integer orderStatus) {
        OrderInfo orderInfo = orderInfoMapper.getOrderInfoByOrderNo(orderNo);
        orderInfo.setOrderStatus(orderStatus);
        orderInfo.setPaymentTime(new Date());
        orderInfo.setPayType(PayTypeEnum.ALIPAY.getCode());

        orderInfoMapper.updateById(orderInfo);
    }
}
